use craftdig_math::Vec3f;

#[derive(Clone, Debug)]
pub struct WorldEnv {
    /// Physics delta time.  This should be `1/tickrate`, but can be adjusted
    /// to simulate slow/fast physics.
    phys_delta_time: f32,

    /// Gravity strength and direction.
    ///
    /// Adjusted for tickrate and applied to velocity every tick.
    gravity: Vec3f,

    /// Multiplier we use for air drag.
    ///
    /// MC param.
    air_drag_mult: f32,

    /// Ground acceleration base multiplier.
    ///
    /// MC param.
    // TODO make property of blocks
    ground_accel_base: f32,

    /// Air acceleration base multiplier.
    ///
    /// MC param.
    // TODO make property of blocks?
    air_accel_base: f32,

    /// Momentum base multiplier.
    ///
    /// MC param.
    momentum_base: f32,
}

impl WorldEnv {
    pub fn new(phys_delta_time: f32) -> Self {
        Self {
            phys_delta_time,
            gravity: Vec3f::new(0.0, -2.0, 0.0),
            air_drag_mult: 0.98,
            ground_accel_base: 0.55,
            air_accel_base: 0.05,
            momentum_base: 0.91,
        }
    }

    /// Copies this instance but changes only the deltatime.
    ///
    /// This is used in the render thread when updating the player-local physics.
    pub fn with_new_dt(&self, delta_time: f32) -> Self {
        Self {
            phys_delta_time: delta_time,
            ..*self
        }
    }

    pub fn phys_delta_time(&self) -> f32 {
        self.phys_delta_time
    }

    pub fn gravity(&self) -> Vec3f {
        self.gravity
    }

    pub fn air_drag_mult(&self) -> f32 {
        self.air_drag_mult
    }

    pub fn ground_accel_base(&self) -> f32 {
        self.ground_accel_base
    }

    pub fn air_accel_base(&self) -> f32 {
        self.air_accel_base
    }

    pub fn momentum_base(&self) -> f32 {
        self.momentum_base
    }
}
